/*
 *  Filename:      gsl_memory.c
 *  Author:         Erick Huang<erickhuang1989@gmail.com>
 *  Revised:       2013-06-03
 *  Description:   GSL Heap Memory management functions.
 *
 *  Copyright (c) Erick Huang. All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gsl_defs.h"
#include "gsl_memory.h"

//#define GSL_MEM_DEBUG_SUPPORT
//#define GSL_MEM_TRACE_SUPPORT
#define GSL_MEM_ERROR_SUPPORT

#ifdef GSL_MEM_DEBUG_SUPPORT
#define GSL_MEM_DEBUG(fmt,arg...)    \
             printf("[DEBUG]%s: "fmt"\n", __FUNCTION__, ##arg)
#else
#define GSL_MEM_DEBUG(fmt,arg...)   do{}while(0)
#endif
#ifdef GSL_MEM_TRACE_SUPPORT
#define GSL_MEM_TRACE()              \
             printf("[TRACE]%s, line:%d\n", __FUNCTION__, __LINE__)
#else 
#define GSL_MEM_TRACE()   do{}while(0)
#endif
#ifdef GSL_MEM_ERROR_SUPPORT
#define GSL_MEM_ERROR(fmt,arg...)    \
             printf("[ERROR]%s: "fmt"\n", __FUNCTION__, ##arg)
#else
#define GSL_MEM_ERROR(fmt,arg...)   do{}while(0)
#endif

void *gsl_mem_alloc(size_t size)
{
	void *ptr;

	if (size == 0) {
		GSL_MEM_ERROR("the given size is zero");
		exit(EXIT_FAILURE);
	}

	ptr = malloc(size);
	if (ptr == NULL) {
		GSL_MEM_ERROR("Memory allocation failure");
		exit(EXIT_FAILURE);
	}
	GSL_MEM_DEBUG("%p: %u", ptr, (unsigned int)size);
	
	return ptr;
}

void *gsl_mem_alloc0(size_t size)
{
	void *ptr = gsl_mem_alloc(size);
	memset(ptr, 0, size);
	return ptr;
}

void gsl_mem_free(void *ptr)
{	
	if (ptr == NULL) {
		GSL_MEM_ERROR("NULL pointer given as argument");
		return;
	}
	free(ptr);
	GSL_MEM_DEBUG("%p => 0", ptr);
}

void *gsl_mem_realloc(void *ptr, size_t size)
{
	if (ptr==NULL || size==0) {
		GSL_MEM_ERROR("error arguments");
		return NULL;
	}
	return realloc(ptr, size);
}


/**
 * gsl_isbufset - 
 * @brief
 *
 *   Is all of the array elements set to a value?
 *
 * @param   buf - buffer to check
 * @param   val - value to check each array element for
 * @param   len - length to check
 *
 * @return  TRUE if all "val"
 *              FALSE otherwise
 */
BOOL_t gsl_isbufset( UINT8 *buf, UINT32 val, UINT32 len )
{
	UINT32 i;

	if (buf == NULL)
		return FALSE;
	for (i = 0; i < len; ++i) {
		// Check for non-initialized value
		if (buf[i] != val)
			return FALSE;
	}

	return TRUE;
}

/**
 * gsl_memdup -
 * @brief   Memory Duplicate - allocates and copies
 */
void *gsl_memdup( const void *src, UINT32 len )
{
	void *ret = NULL;
	
	if (src == NULL)
		return ret;

	ret = gsl_mem_alloc(len);
	memcpy(ret, src, len);
	return ret;
}

